package com.babel.util.ciphers;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSON;

/**
 * 平台内部支付加密工具类
 * 
 * @author Kun
 * @date 2017-7-13 17:09:54
 */
public class PaySecurityUtils {

	public static String digestHmac(String key, String message) {
		return RSA.base64(HMAC.digest(message, key.getBytes()));
	}

	public static String digestHmac(String key, String signName, Map<String, Object> msgMap) {
		System.out.println(getSignData(signName, msgMap));
		return digestHmac(key, getSignData(signName, msgMap));
	}

	/**
	 * 验签
	 * 
	 * @param key
	 * @param signName
	 * @param msgMap
	 * @return
	 */
	public static boolean signHmac(String key, String signName, Map<String, Object> msgMap) {
		String signStr = (String) msgMap.get(signName);
		if (isEmpty(signStr)) {
			return false;
		}
		return signStr.equals(digestHmac(key, signName, msgMap));
	}

	/**
	 * RSA加密
	 * 
	 * @param key
	 *            公钥
	 * @param message
	 *            加密原始数据
	 * @return
	 */
	public static String encryptRsa(String key, String message) {
		return RSA.encrypt(key, message);
	}

	/**
	 * @param key
	 * @param msgMap
	 *            加密原始数据Map
	 * @return
	 */
	public static String encryptRsa(String key, Map<String, String> msgMap) {
		return RSA.encrypt(key, JSON.toJSONString(msgMap));
	}

	/**
	 * RSA解密
	 * 
	 * @param key
	 *            私钥
	 * @param message
	 *            加密字符串
	 * @return
	 */
	public static String decryptRsa(String key, String message) {
		return RSA.decrypt(key, message);
	}

	/**
	 * RSA解密
	 * 
	 * @param key
	 *            私钥
	 * @param message
	 *            加密字符串
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, Object> decryptRsa2Map(String key, String message) {
		return (Map<String, Object>) JSON.parse(RSA.decrypt(key, message));
	}

//	/**
//	 * 使用默认排序
//	 * 
//	 * @param signName
//	 * @param params
//	 * @return
//	 */
//	public static String getSignData(Map<String, Object> params) {
//		return getSignData(null, params);
//	}

	/**
	 * 使用默认排序
	 * 
	 * @param signName
	 * @param params
	 * @return
	 */
	public static String getSignData(String signName, Map<String, Object> params) {
		StringBuffer content = new StringBuffer();
		List<String> keys = new ArrayList<String>(params.keySet());
		Collections.sort(keys);
		for (int i = 0; i < keys.size(); i++) {
			String key = keys.get(i);
			if (isEmpty(signName) || !signName.equals(key)) {
				String value = String.valueOf(params.get(key));
				value = null == value ? "" : value;
				content.append("&" + key + "=" + value);
			}
		}
		String str = content.toString();
		if (isEmpty(str)) {
			return str;
		}
		if (str.startsWith("&")) {
			return str.substring("&".length());
		}
		return str;
	}
	
	private static boolean isEmpty(String str) {
		return (str == null) || (str.trim().length() == 0);
	}
	
	/**
	 * @param obj
	 * @param includeNull
	 *            是否包含空字符串""
	 * @return
	 */
	public static Map<String, Object> toMap(Object obj, boolean includeNull) {
		if (obj == null) {
			return null;
		}
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
			PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
			for (PropertyDescriptor property : propertyDescriptors) {
				String key = property.getName();
				if (!"class".equals(key)) {
					Method getter = property.getReadMethod();
					Object value = getter.invoke(obj);
					if (value != null && (includeNull || isEmpty(String.valueOf(value)))) {
						map.put(key, value== null ? null : value);
					}
				}
			}
		} catch (Exception e) {
			throw new IllegalStateException("convert javabean to map failed", e);
		}
		return map;
	}
}
